<?php

class Application {

    public static $uri;
    public static $controller;
    public static $method;
    public static $params;

    public static function init($url)
    {
	if (!preg_match('/[^A-Za-z0-9\:\/\.\-\_\#]/i', $url))
	{
	    //creates an array from the rest of the URL
	    $array_tmp_uri = preg_split('[\\/]', $url, -1, PREG_SPLIT_NO_EMPTY);

	    //Here, we will define what is what in the URL
	    if (isset($array_tmp_uri[0]))
	    {
		$array_uri['controller'] = array_shift($array_tmp_uri); //The controller class
	    }
	    else
		$array_uri['controller'] = 'home'; // default controller

	    if (isset($array_tmp_uri[0]))
	    {
		$array_uri['method'] = array_shift($array_tmp_uri); //The method
	    }
	    else
		$array_uri['method'] = 'index'; // default method

	    if (count($array_tmp_uri) > 0)
		$array_uri['params'] = $array_tmp_uri; //The params
	    else
		$array_uri['params'] = array();

	    self::$uri = $array_uri;
            self::$uri['controller'] = Translator::to_eng(self::$uri['controller']);
            self::$uri['method'] = Translator::to_eng(self::$uri['method']);
	    self::$controller = self::format_controller_class();
	    self::$method = self::format_method();
	    self::$params = self::$uri['params'];
	}
	else
	{
	    self::error('Url contains non-authorized chars !');
	}
    }

    public static function run($controller=null, $method=null, $params=array())
    {
	// Set properties if there are params in the function
	if (isset($controller) and isset($method))
	{
	    self::$controller = $controller;
	    self::$method = $method;
	    self::$params = $params;
	}

	self::show_uri();

	// Load the controller
	$controller_class = self::$controller . '_Controller';
	$file = "application/controllers/" . self::format_controller_file() . ".php";
	if (file_exists($file))
	{
	    require_once($file);
	    $controller = new $controller_class();
	    $method = self::$method;
	    $params = self::$params;
	    if (is_object($controller))
	    {
		if (method_exists($controller, $method))
		{
		    if (is_callable(array($controller, $method)))
		    {
			$controller->{$method}($params);
		    }
		    else if (is_callable(array($controller, 'index')))
		    {
			self::run('Home', 'index');
		    }
		    else
		    {
			self::error('404');
		    }
		}
		else
		{
		    self::run('Home', 'index');
		}
	    }
	}
	else
	{
	    self::error('404');
	}
    }

    public static function exception_handler(Exception $e)
    {
	try
	{
	    $type = get_class($e);
	    $code = $e->getCode();
	    $message = $e->getMessage();
	    $file = $e->getFile();
	    $line = $e->getLine();
	    $trace = $e->getTraceAsString();

	    $errors = array(
		E_ERROR => 'Fatal Error',
		E_USER_ERROR => 'User Error',
		E_PARSE => 'Parse Error',
		E_WARNING => 'Warning',
		E_USER_WARNING => 'User Warning',
		E_STRICT => 'Strict',
		E_NOTICE => 'Notice',
		E_RECOVERABLE_ERROR => 'Recoverable Error',
	    );
	    if (isset($errors[$code]))
	    {
		$code = $errors[$code];
	    }

	    if (!headers_sent())
		header('HTTP/1.1 500 Internal Server Error');
	    if (DEVELOPMENT_ENVIRONMENT)
		self::run('Error', 'index', array("'$message' in $file($line)\n\nCall Stack:\n$trace"));
	    else
		self::run('Error', 'index', array($message));
	}
	catch (Exception $e)
	{
	    echo strip_tags($e->getMessage()) . ' on ' . $e->getFile() . ' line [' . $e->getLine() . "]\n";
	    exit(1);
	}
    }

    public static function format_controller_class()
    {
	return ucfirst(Inflect::singularize(self::$uri['controller']));
    }

    public static function format_controller_file()
    {
	return strtolower(self::$controller);
    }

    public static function format_method()
    {
	return strtolower(str_replace('-', '_', self::$uri['method']));
    }

    public static function error($message)
    {
	self::run('Error', 'index', array($message));
	exit(1);
    }

    public static function show_uri()
    {
	echo '<u>URI Details</u><br/>Controller : ' . self::$controller . '<br/>
	    Method : ' . self::$method . '<br/>Params :';
	print_r(self::$params);
	echo'<br/><br/>';
    }

}
